package org.vacoor.xqq.ui.comp.tree;

import javax.swing.*;
import java.awt.*;

/**
 * 头像抖动效果, 由于 TreeCellRenderer 是无状态的, 因此,这里只控制在指定位置 repaint
 * <p/>
 * 如果直接继承 {@link javax.swing.JComponent} 有时候会丢失宽度, 原因不清楚, 暂时继承JLabel解决
 *
 * @author Vacoor
 */
public class ShakeAvatar extends JLabel {
    private static final Insets NORMAL_PADDING = new Insets(1, 1, 1, 1);

    private Icon icon;
    private int status;

    public ShakeAvatar() {
        this(null);
    }

    public ShakeAvatar(Icon icon) {
        this.setIcon(icon);
        this.setBorder(null);
    }

    @Override
    protected void paintComponent(Graphics g) {
        Icon icon = getIcon();
        if (icon == null || Shakeable.HIDDEN == status) {
            return;
        }
        Insets padding = calculatePadding(NORMAL_PADDING, status);
        icon.paintIcon(this, g, padding.left, padding.top);
    }

    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
        repaintStatus();
    }

    public void resetStatus() {
        setStatus(Shakeable.NORMAL);
    }

    private void repaintStatus() {
        this.repaint();
    }

    protected Insets calculatePadding(Insets defaultPadding, int status) {
        if ((Shakeable.HIDDEN & status) != 0) {
            return defaultPadding;
        }
        Insets padding = (Insets) defaultPadding.clone();
        if ((Shakeable.TOP & status) == 0 || (Shakeable.BOTTOM & status) == 0) {
            // TOP
            if ((Shakeable.TOP & status) != 0) {
                padding.top = 0;
                padding.bottom += defaultPadding.top;

                // BOTTOM
            } else if ((Shakeable.BOTTOM & status) != 0) {
                padding.bottom = 0;
                padding.top += defaultPadding.bottom;
            }
        }

        if ((Shakeable.LEFT & status) == 0 || (Shakeable.RIGHT & status) == 0) {
            // LEFT
            if ((Shakeable.LEFT & status) != 0) {
                padding.left = 0;
                padding.right = defaultPadding.left + defaultPadding.right;

                // RIGHT
            } else if ((Shakeable.RIGHT & status) != 0) {
                padding.right = padding.left + padding.right - defaultPadding.left;
                padding.left = defaultPadding.left + defaultPadding.right - padding.right;
            }
        }
        return padding;
    }

    public void setIcon(Icon icon) {
        super.setIcon(icon);
        this.icon = icon;
        if (icon != null) super.setPreferredSize(new Dimension(icon.getIconWidth(), icon.getIconHeight()));
        resetStatus();
    }

    public Icon getIcon() {
        return this.icon;
    }
}
